home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / perl / Perl / ext / SDBM_File / sdbm / dbe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-18  |  9.6 KB  |  436 lines

  1. #include <stdio.h>
  2. #ifndef VMS
  3. #include <sys/file.h>
  4. #include <ndbm.h>
  5. #else
  6. #include "file.h"
  7. #include "ndbm.h"
  8. #endif
  9. #include <ctype.h>
  10.  
  11. /***************************************************************************\
  12. **                                                                         **
  13. **   Function name: getopt()                                               **
  14. **   Author:        Henry Spencer, UofT                                    **
  15. **   Coding date:   84/04/28                                               **
  16. **                                                                         **
  17. **   Description:                                                          **
  18. **                                                                         **
  19. **   Parses argv[] for arguments.                                          **
  20. **   Works with Whitesmith's C compiler.                                   **
  21. **                                                                         **
  22. **   Inputs   - The number of arguments                                    **
  23. **            - The base address of the array of arguments                 **
  24. **            - A string listing the valid options (':' indicates an       **
  25. **              argument to the preceding option is required, a ';'        **
  26. **              indicates an argument to the preceding option is optional) **
  27. **                                                                         **
  28. **   Outputs  - Returns the next option character,                         **
  29. **              '?' for non '-' arguments                                  **
  30. **              or ':' when there is no more arguments.                    **
  31. **                                                                         **
  32. **   Side Effects + The argument to an option is pointed to by 'optarg'    **
  33. **                                                                         **
  34. *****************************************************************************
  35. **                                                                         **
  36. **   REVISION HISTORY:                                                     **
  37. **                                                                         **
  38. **     DATE           NAME                        DESCRIPTION              **
  39. **   YY/MM/DD  ------------------   ------------------------------------   **
  40. **   88/10/20  Janick Bergeron      Returns '?' on unamed arguments        **
  41. **                                  returns '!' on unknown options         **
  42. **                                  and 'EOF' only when exhausted.         **
  43. **   88/11/18  Janick Bergeron      Return ':' when no more arguments      **
  44. **   89/08/11  Janick Bergeron      Optional optarg when ';' in optstring  **
  45. **                                                                         **
  46. \***************************************************************************/
  47.  
  48. char *optarg;                   /* Global argument pointer. */
  49.  
  50. #ifdef VMS
  51. #define index  strchr
  52. #endif
  53.  
  54. char
  55. getopt(argc, argv, optstring)
  56. int argc;
  57. char **argv;
  58. char *optstring;
  59. {
  60.     register int c;
  61.     register char *place;
  62.     extern char *index();
  63.     static int optind = 0;
  64.     static char *scan = NULL;
  65.  
  66.     optarg = NULL;
  67.  
  68.     if (scan == NULL || *scan == '\0') {
  69.  
  70.         if (optind == 0)
  71.             optind++;
  72.         if (optind >= argc)
  73.             return ':';
  74.  
  75.         optarg = place = argv[optind++];
  76.         if (place[0] != '-' || place[1] == '\0')
  77.             return '?';
  78.         if (place[1] == '-' && place[2] == '\0')
  79.             return '?';
  80.         scan = place + 1;
  81.     }
  82.  
  83.     c = *scan++;
  84.     place = index(optstring, c);
  85.     if (place == NULL || c == ':' || c == ';') {
  86.  
  87.         (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
  88.         scan = NULL;
  89.         return '!';
  90.     }
  91.     if (*++place == ':') {
  92.  
  93.         if (*scan != '\0') {
  94.  
  95.             optarg = scan;
  96.             scan = NULL;
  97.  
  98.         }
  99.         else {
  100.  
  101.             if (optind >= argc) {
  102.  
  103.                 (void) fprintf(stderr, "%s: %c requires an argument\n",
  104.                            argv[0], c);
  105.                 return '!';
  106.             }
  107.             optarg = argv[optind];
  108.             optind++;
  109.         }
  110.     }
  111.     else if (*place == ';') {
  112.  
  113.         if (*scan != '\0') {
  114.  
  115.             optarg = scan;
  116.             scan = NULL;
  117.  
  118.         }
  119.         else {
  120.  
  121.             if (optind >= argc || *argv[optind] == '-')
  122.                 optarg = NULL;
  123.             else {
  124.                 optarg = argv[optind];
  125.                 optind++;
  126.             }
  127.         }
  128.     }
  129.     return c;
  130. }
  131.  
  132.  
  133. void
  134. print_datum(db)
  135. datum db;
  136. {
  137.     int i;
  138.  
  139.     putchar('"');
  140.     for (i = 0; i < db.dsize; i++) {
  141.         if (isprint(db.dptr[i]))
  142.             putchar(db.dptr[i]);
  143.         else {
  144.             putchar('\\');
  145.             putchar('0' + ((db.dptr[i] >> 6) & 0x07));
  146.             putchar('0' + ((db.dptr[i] >> 3) & 0x07));
  147.             putchar('0' + (db.dptr[i] & 0x07));
  148.         }
  149.     }
  150.     putchar('"');
  151. }
  152.  
  153.  
  154. datum
  155. read_datum(s)
  156. char *s;
  157. {
  158.     datum db;
  159.     char *p;
  160.     int i;
  161.  
  162.     db.dsize = 0;
  163.     db.dptr = (char *) malloc(strlen(s) * sizeof(char));
  164.     for (p = db.dptr; *s != '\0'; p++, db.dsize++, s++) {
  165.         if (*s == '\\') {
  166.             if (*++s == 'n')
  167.                 *p = '\n';
  168.             else if (*s == 'r')
  169.                 *p = '\r';
  170.             else if (*s == 'f')
  171.                 *p = '\f';
  172.             else if (*s == 't')
  173.                 *p = '\t';
  174.             else if (isdigit(*s) && isdigit(*(s + 1)) && isdigit(*(s + 2))) {
  175.                 i = (*s++ - '0') << 6;
  176.                 i |= (*s++ - '0') << 3;
  177.                 i |= *s - '0';
  178.                 *p = i;
  179.             }
  180.             else if (*s == '0')
  181.                 *p = '\0';
  182.             else
  183.                 *p = *s;
  184.         }
  185.         else
  186.             *p = *s;
  187.     }
  188.  
  189.     return db;
  190. }
  191.  
  192.  
  193. char *
  194. key2s(db)
  195. datum db;
  196. {
  197.     char *buf;
  198.     char *p1, *p2;
  199.  
  200.     buf = (char *) malloc((db.dsize + 1) * sizeof(char));
  201.     for (p1 = buf, p2 = db.dptr; *p2 != '\0'; *p1++ = *p2++);
  202.     *p1 = '\0';
  203.     return buf;
  204. }
  205.  
  206.  
  207. main(argc, argv)
  208. int argc;
  209. char **argv;
  210. {
  211.     typedef enum {
  212.         YOW, FETCH, STORE, DELETE, SCAN, REGEXP
  213.     } commands;
  214.     char opt;
  215.     int flags;
  216.     int giveusage = 0;
  217.     int verbose = 0;
  218.     commands what = YOW;
  219.     char *comarg[3];
  220.     int st_flag = DBM_INSERT;
  221.     int argn;
  222.     DBM *db;
  223.     datum key;
  224.     datum content;
  225.  
  226.     flags = O_RDWR;
  227.     argn = 0;
  228.  
  229.     while ((opt = getopt(argc, argv, "acdfFm:rstvx")) != ':') {
  230.         switch (opt) {
  231.         case 'a':
  232.             what = SCAN;
  233.             break;
  234.         case 'c':
  235.             flags |= O_CREAT;
  236.             break;
  237.         case 'd':
  238.             what = DELETE;
  239.             break;
  240.         case 'f':
  241.             what = FETCH;
  242.             break;
  243.         case 'F':
  244.             what = REGEXP;
  245.             break;
  246.         case 'm':
  247.             flags &= ~(000007);
  248.             if (strcmp(optarg, "r") == 0)
  249.                 flags |= O_RDONLY;
  250.             else if (strcmp(optarg, "w") == 0)
  251.                 flags |= O_WRONLY;
  252.             else if (strcmp(optarg, "rw") == 0)
  253.                 flags |= O_RDWR;
  254.             else {
  255.                 fprintf(stderr, "Invalid mode: \"%s\"\n", optarg);
  256.                 giveusage = 1;
  257.             }
  258.             break;
  259.         case 'r':
  260.             st_flag = DBM_REPLACE;
  261.             break;
  262.         case 's':
  263.             what = STORE;
  264.             break;
  265.         case 't':
  266.             flags |= O_TRUNC;
  267.             break;
  268.         case 'v':
  269.             verbose = 1;
  270.             break;
  271.         case 'x':
  272.             flags |= O_EXCL;
  273.             break;
  274.         case '!':
  275.             giveusage = 1;
  276.             break;
  277.         case '?':
  278.             if (argn < 3)
  279.                 comarg[argn++] = optarg;
  280.             else {
  281.                 fprintf(stderr, "Too many arguments.\n");
  282.                 giveusage = 1;
  283.             }
  284.             break;
  285.         }
  286.     }
  287.  
  288.     if (giveusage | what == YOW | argn < 1) {
  289.         fprintf(stderr, "Usage: %s databse [-m r|w|rw] [-crtx] -a|-d|-f|-F|-s [key [content]]\n", argv[0]);
  290.         exit(-1);
  291.     }
  292.  
  293.     if ((db = dbm_open(comarg[0], flags, 0777)) == NULL) {
  294.         fprintf(stderr, "Error opening database \"%s\"\n", comarg[0]);
  295.         exit(-1);
  296.     }
  297.  
  298.     if (argn > 1)
  299.         key = read_datum(comarg[1]);
  300.     if (argn > 2)
  301.         content = read_datum(comarg[2]);
  302.  
  303.     switch (what) {
  304.  
  305.     case SCAN:
  306.         key = dbm_firstkey(db);
  307.         if (dbm_error(db)) {
  308.             fprintf(stderr, "Error when fetching first key\n");
  309.             goto db_exit;
  310.         }
  311.         while (key.dptr != NULL) {
  312.             content = dbm_fetch(db, key);
  313.             if (dbm_error(db)) {
  314.                 fprintf(stderr, "Error when fetching ");
  315.                 print_datum(key);
  316.                 printf("\n");
  317.                 goto db_exit;
  318.             }
  319.             print_datum(key);
  320.             printf(": ");
  321.             print_datum(content);
  322.             printf("\n");
  323.             if (dbm_error(db)) {
  324.                 fprintf(stderr, "Error when fetching next key\n");
  325.                 goto db_exit;
  326.             }
  327.             key = dbm_nextkey(db);
  328.         }
  329.         break;
  330.  
  331.     case REGEXP:
  332.         if (argn < 2) {
  333.             fprintf(stderr, "Missing regular expression.\n");
  334.             goto db_exit;
  335.         }
  336.         if (re_comp(comarg[1])) {
  337.             fprintf(stderr, "Invalid regular expression\n");
  338.             goto db_exit;
  339.         }
  340.         key = dbm_firstkey(db);
  341.         if (dbm_error(db)) {
  342.             fprintf(stderr, "Error when fetching first key\n");
  343.             goto db_exit;
  344.         }
  345.         while (key.dptr != NULL) {
  346.             if (re_exec(key2s(key))) {
  347.                 content = dbm_fetch(db, key);
  348.                 if (dbm_error(db)) {
  349.                     fprintf(stderr, "Error when fetching ");
  350.                     print_datum(key);
  351.                     printf("\n");
  352.                     goto db_exit;
  353.                 }
  354.                 print_datum(key);
  355.                 printf(": ");
  356.                 print_datum(content);
  357.                 printf("\n");
  358.                 if (dbm_error(db)) {
  359.                     fprintf(stderr, "Error when fetching next key\n");
  360.                     goto db_exit;
  361.                 }
  362.             }
  363.             key = dbm_nextkey(db);
  364.         }
  365.         break;
  366.  
  367.     case FETCH:
  368.         if (argn < 2) {
  369.             fprintf(stderr, "Missing fetch key.\n");
  370.             goto db_exit;
  371.         }
  372.         content = dbm_fetch(db, key);
  373.         if (dbm_error(db)) {
  374.             fprintf(stderr, "Error when fetching ");
  375.             print_datum(key);
  376.             printf("\n");
  377.             goto db_exit;
  378.         }
  379.         if (content.dptr == NULL) {
  380.             fprintf(stderr, "Cannot find ");
  381.             print_datum(key);
  382.             printf("\n");
  383.             goto db_exit;
  384.         }
  385.         print_datum(key);
  386.         printf(": ");
  387.         print_datum(content);
  388.         printf("\n");
  389.         break;
  390.  
  391.     case DELETE:
  392.         if (argn < 2) {
  393.             fprintf(stderr, "Missing delete key.\n");
  394.             goto db_exit;
  395.         }
  396.         if (dbm_delete(db, key) || dbm_error(db)) {
  397.             fprintf(stderr, "Error when deleting ");
  398.             print_datum(key);
  399.             printf("\n");
  400.             goto db_exit;
  401.         }
  402.         if (verbose) {
  403.             print_datum(key);
  404.             printf(": DELETED\n");
  405.         }
  406.         break;
  407.  
  408.     case STORE:
  409.         if (argn < 3) {
  410.             fprintf(stderr, "Missing key and/or content.\n");
  411.             goto db_exit;
  412.         }
  413.         if (dbm_store(db, key, content, st_flag) || dbm_error(db)) {
  414.             fprintf(stderr, "Error when storing ");
  415.             print_datum(key);
  416.             printf("\n");
  417.             goto db_exit;
  418.         }
  419.         if (verbose) {
  420.             print_datum(key);
  421.             printf(": ");
  422.             print_datum(content);
  423.             printf(" STORED\n");
  424.         }
  425.         break;
  426.     }
  427.  
  428. db_exit:
  429.     dbm_clearerr(db);
  430.     dbm_close(db);
  431.     if (dbm_error(db)) {
  432.         fprintf(stderr, "Error closing database \"%s\"\n", comarg[0]);
  433.         exit(-1);
  434.     }
  435. }
  436.